﻿using CGT.API.Common;
using OF.Utility;
using OF.Utility.Logging;
using OF.Utility.WxPayAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;

namespace CGT.API.Controllers
{
    /// <summary>
    /// 微信支付
    /// </summary>
    public class WxPayController : ApiController
    {
        #region 支付回调

        /// <summary>
        /// 支付宝支付异步回调
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public string NotifyCallBack()
        {
            WxPayData data = GetNotifyData();
            if (data.GetValue("return_code").ToString() == "SUCCESS" && data.GetValue("result_code").ToString() == "SUCCESS")
            {
                string out_trade_no = data.GetValue("out_trade_no").ToString();
                //long orderId = OrderService.TradeNumToOrderId(out_trade_no);
                //if (orderId == 0)
                //{
                //    return PayErrorBack("订单不存在").ToXml();
                //}

                //try
                //{

                //    //交易单号
                //    string transaction_id = data.GetValue("transaction_id").ToString();
                //    //扩展信息
                //    string attach = HttpUtility.UrlDecode(data.GetValue("attach").ToString());
                //    var dic = OrderService.DeserializeParams(attach);
                //    OrderTypeEnum orderType = OrderTypeEnum.Order;
                //    if (dic != null && dic["OrderType"] == "additional")
                //    {
                //        orderType = OrderTypeEnum.Additional;
                //    }
                //    if (OrderService.PaySucess(transaction_id, orderId, PayTypeEnum.WeiXin, orderType))
                //    {
                data = PaySuccessBack();
                //    }
                //}
                //catch (Exception ex)
                //{
                //    data = PayErrorBack(ex.Message);
                //}
            }

            return data.ToXml();
        }

        /// <summary>
        /// 接收从微信支付后台发送过来的数据并验证签名
        /// </summary>
        /// <returns>微信支付后台返回的数据</returns>
        public WxPayData GetNotifyData()
        {
            //接收从微信后台POST过来的数据
            System.IO.Stream s = HttpContext.Current.Request.InputStream;
            int count = 0;
            byte[] buffer = new byte[1024];
            StringBuilder builder = new StringBuilder();
            while ((count = s.Read(buffer, 0, 1024)) > 0)
            {
                builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
            }
            s.Flush();
            s.Close();
            s.Dispose();

            //ActionLogOperate.Insert(new OF.Component.Model.ActionLogInfo()
            //{
            //    CreatedDate = DateTime.Now,
            //    Platform = 4,
            //    PostData = builder.ToString(),
            //    RequestMethod = "WxPay",
            //    RequestUrl = Request.RequestUri.PathAndQuery
            //});

            //转换数据格式并验证签名
            WxPayData data = new WxPayData(null);
            try
            {
                data.FromXml(builder.ToString());
                Log4netLog.Debug("WxPay-NotifyCallBack:" + buffer.ToString());
            }
            catch (WxPayException ex)
            {
                Log4netLog.Debug("WxPay-NotifyCallBack:" + ex.Message);
                //若签名错误，则立即返回结果给微信支付后台
                data = PayErrorBack(ex.Message);
            }
            return data;
        }

        /// <summary>
        /// 成功回调
        /// </summary>
        protected WxPayData PaySuccessBack()
        {
            WxPayData res = new WxPayData(null);
            res.SetValue("return_code", "SUCCESS");
            res.SetValue("return_msg", "OK");
            return res;
        }

        /// <summary>
        /// 失败回调
        /// </summary>
        /// <param name="msg"></param>
        protected WxPayData PayErrorBack(string msg)
        {
            //ErrorLogOperate.Insert(new OF.Component.Model.ErrorLogInfo()
            //{
            //    CreatedDate = DateTime.Now,
            //    Platform = 4,
            //    ErrorMessage = msg,
            //    RequestMethod = "WxPay",
            //    RequestUrl = Request.RequestUri.PathAndQuery
            //});

            WxPayData res = new WxPayData(null);
            res.SetValue("return_code", "FAIL");
            res.SetValue("return_msg", msg);
            return res;
        }

        #endregion

        #region 申请退款

        /// <summary>
        /// 申请退款
        /// </summary>
        /// <param name="orderId">订单ID</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public ResultData<string> ApplyRefund(long orderId)
        {
            //string result = OrderService.RefundApply(orderId, OF.Component.Enum.RefundTypeEnum.All, "微信小程序用户申请退款");
            //if (string.IsNullOrEmpty(result))
            //{
            //    return ResultData<string>.Success();
            //}
            //return ResultData<string>.Error(result);
            return ResultData<string>.Success();
        }

        #endregion

        #region 发起支付

        /// <summary>
        /// 验车上牌 支付
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <param name="openId">openid</param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public ResultData<SortedDictionary<string, object>> WxMiniPay(long orderId, string openId)
        {
            WxMiniPayConfig config = new WxMiniPayConfig();
            return GetWxpayTradeAppPay(orderId, "车管在线-验车订单", config, openId);
        }

        /// <summary>
        /// 获取支付字符串
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <param name="subject"></param>
        /// <param name="config"></param>
        /// <param name="openId"></param>
        /// <returns></returns>
        private ResultData<SortedDictionary<string, object>> GetWxpayTradeAppPay(long orderId, string subject, IConfig config, string openId)
        {
            ResultData<SortedDictionary<string, object>> rdata = new ResultData<SortedDictionary<string, object>>();
            decimal needPayPrice = 1;


            //防止订单号重复，以原始订单号为基础构造一个虚拟个订单号，在回调时再还原为原始订单号
            // var out_trade_no = OrderService.OrderIdToTradeNum(orderId);
            var out_trade_no = DateTime.Now.ToString("yyyyMMddHHmmss");

            WxPayApi WxApi = new WxPayApi(config);
            WxPayData payData = new WxPayData(config);
            payData.SetValue("appid", config.GetAppID());  //应用ID
            payData.SetValue("mch_id", config.GetMchID());  //商户号
            payData.SetValue("nonce_str", WxPayApi.GenerateNonceStr());

            //payData.SetValue("attach", HttpUtility.UrlEncode("OrderType=" + orderType));//附加数据
            payData.SetValue("body", subject);  //商品描述
            payData.SetValue("out_trade_no", out_trade_no); //商户订单号
            payData.SetValue("total_fee", Convert.ToInt32(needPayPrice));  //总金额
            payData.SetValue("trade_type", "JSAPI");  //交易类型
            payData.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));  //交易起始时间
            payData.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));  //交易结束时间
            payData.SetValue("notify_url", config.GetNotifyUrl());  //通知地址
            payData.SetValue("openid", openId);
            payData.SetValue("sign", payData.MakeSign(WxPayData.SIGN_TYPE_MD5));

            WxPayData rPayData = new WxPayData(config);
            try
            {

                rPayData = WxApi.UnifiedOrder(payData);
                Log4netLog.Debug("WxPay-WxMiniPay:" + rPayData.ToJson());
                payData = new WxPayData(config);
                payData.SetValue("appId", config.GetAppID());  //预支付交易会话ID
                payData.SetValue("package", "prepay_id=" + rPayData.GetValue("prepay_id"));  //扩展字段
                payData.SetValue("signType", WxPayData.SIGN_TYPE_MD5);  //预支付交易会话ID
                payData.SetValue("nonceStr", WxPayApi.GenerateNonceStr());  //随机字符串
                payData.SetValue("timeStamp", WxPayApi.GenerateTimeStamp());  //时间戳
                payData.SetValue("paySign", payData.MakeSign(WxPayData.SIGN_TYPE_MD5));  //签名
                rdata.data = payData.GetValues();
            }
            catch (Exception ex)
            {
                Log4netLog.Debug("WxPay-WxMiniPay:" + ex.Message);
                //ErrorLogOperate.Insert(new OF.Component.Model.ErrorLogInfo()
                //{
                //    CreatedDate = DateTime.Now,
                //    Platform = 4,
                //    ErrorMessage = string.Format("支付成功但更新订单状态时出错,订单ID:{0}，错误原因:{1}", orderId, ex.Message),
                //    RequestMethod = "AliPay",
                //    RequestUrl = Request.RequestUri.AbsoluteUri
                //});
                rdata.message = "支付时发生异常" + ex.ToString();
            }
            return rdata;
        }

        #endregion
    }
}
